#include <OpenNetwork/OpenNetwork.h>
#include <iostream>

using namespace onet;
using namespace std;

//! Own Message types
#define MSG_Hi EMT_Custom+1

//! States we have to keep track of
bool received = true;
PeerID peerId = -1;

u32 receiveCount = 0;
u32 sendCount = 0;

//! Setttings
const EPortType portType = EPT_TransmissionControlProtocol;
const u32 intervall = 1000;

class SendCallback : public INetworkCallback
{
    public:
        virtual void onCreate(const INetworkPort* port)
        {
            //Setup Values
            receiveCount = 0;
            sendCount = 0;
            peerId = -1;
            received = true;
        }

        virtual void onPeerConnect(const PeerID id)
        {
            peerId = id;

            cout << "Connected!" << endl;
        }
};

class ReceiveCallback : public INetworkCallback
{
    public:
        virtual void onMessageReceived(const PeerID id, u8 type, u32 length, c8* data, bool reliable)
        {
            if(type != MSG_Hi)
            {
                cout << "Strange Message" << endl;
                return;
            }

            received = true;
            receiveCount++;

            cout << "Received" << endl;
        }
};

int main()
{
    SendCallback sendCallback;
    ReceiveCallback receiveCallback;

    start();

    INetworkPort* sender = createNetworkPort(portType, &sendCallback, 1, 60000, false, false);
    INetworkPort* receiver = createNetworkPort(portType, &receiveCallback, 1, 60001, true, false);
    cout << "Initializing...";

    if(!sender->init() || !receiver->init())
    {
        cout << "Error!" << endl;

        delete sender;
        delete receiver;

        end();

        return -1;
    }
    else
        cout << "Done" << endl;

    c8* data = new c8[100];

    cout << "Connecting...";

    if(!sender->connect(createAddressFromURL("localhost", receiver->getPortNumber())))
        cout << "Error!" << endl;
    else
    {
        while(peerId == -1)
        {
            receiver->work();
            sender->work();
        }

        u32 start = getLocalTime();

        while((start + intervall) > getLocalTime())
        {
            if(received)
            {
                //!Send new data
                sender->send(peerId, MSG_Hi, 100, data, false);

                cout << "Sending...";

                sendCount++;

                received = false;
            }

            sender->work();
            receiver->work();
        }
    }

    delete data;
    delete sender;
    delete receiver;

    end();

    cout << endl;
    cout << endl;
    cout << endl;

    cout << "In " << intervall << " milliseconds: " << endl;
    cout << "-----------------------" << endl;
    cout << sendCount << " Messages sent." << endl;
    cout << receiveCount << " Messages received." << endl;

    return 1;
}
